package com.asframe.conf
{
	import com.asframe.collections.maps.HashMap;
	import com.asframe.pattern.Singleton;
	import com.asframe.ref.Metadata;
	import com.asframe.ref.RefConts;
	import com.asframe.ref.Type;
	import com.asframe.ref.Variable;
	import com.asframe.utils.ClassUtils;
	import com.asframe.utils.RefUtils;

	import flash.system.ApplicationDomain;

	public class JsonConfig extends Singleton
	{
		private var cacheType:HashMap = new HashMap();

		private static var instance:JsonConfig;
		/**
		 * 获取实例的静态方法实例
		 * @return
		 *
		 */
		public static function getInstance():JsonConfig
		{
			if(instance == null)
			{
				instance = new JsonConfig();
			}
			return instance;
		}

		public function configToJson(config:*, target:* = null, applicationDomain:ApplicationDomain = null):*
		{
			var jsonData:Object = JSON.parse(config);
			if(target == null)
			{
				return jsonData;
			}
			//转换指定的target
			jsonToObject(jsonData,target);
			return target;
		}

		public function jsonToObject(jsonData:Object,target:*):*
		{
			var variable:Variable = null;
			var type:Type = getType(target);
			var propertyType:String = null;
			var metadata:Metadata = null;
			for(var key:* in jsonData)
			{
				variable = type.getVariable(key);
				if(variable == null)
				{
					throw new Error(target + "转换错误，没有" + key + "属性");
				}
				propertyType = variable.type;

				if(propertyType == RefConts.OBJECT_TYPE)
				{
					metadata = variable.getMetadata(RefConts.MAP_TYPE);
					if(metadata != null)
					{
						propertyType = metadata.firestArg.value;
						var map:Object = {};
						var objData:Object = jsonData[key];
						for(var mapKey:* in objData)
						{
							map[mapKey] = jsonToObject(objData[mapKey],RefUtils.refObject(propertyType));
						}
						target[key] = map;
					}
					else
					{
						//没有元标签，则直接保存
						target[key] = jsonData[key];
					}
				}
				//只处理数组和对象
				else if(propertyType == RefConts.BOOLEAN_TYPE || propertyType == RefConts.INT_TYPE
					|| propertyType == RefConts.NUMBER_TYPE || propertyType == RefConts.UINT_TYPE
					|| propertyType == RefConts.STRING_TYPE)
				{
					target[key] = jsonData[key];
				}
				else if(propertyType == RefConts.ARRAY_TYPE)
				{
					//查看是否有Class标签
					metadata = variable.getMetadata(RefConts.CLASS_TYPE);
					if(metadata != null && metadata.firestArg != null)
					{
						propertyType = metadata.firestArg.value;
						target[key] = fillArrayValue(jsonData[key],[],propertyType);
					}
					else
					{
						target[key] = fillArrayValue(jsonData[key],[],null);
					}
				}
				else if(propertyType.indexOf("__AS3__.vec.Vector") != -1)
				{
					//查看是否有类型
					var tempAry:Array = propertyType.split("<");
					if(tempAry.length > 1)
					{
						tempAry = tempAry[1].split(">");
						propertyType = tempAry[0];
					}
					target[key] = fillArrayValue(jsonData[key],RefUtils.refObject(variable.type),propertyType);
				}
				else
				{
					//对象
					var tempObj:* = RefUtils.refObject(propertyType,null);
					target[key] = tempObj;
					jsonToObject(jsonData[key],tempObj);
				}
			}
			return target;
		}
		public function fillArrayValue(jsonArray:Array,valueAry:*,propertyType:String):*
		{
			var target:* = null;
			for each(var jsonData:* in jsonArray)
			{
				if(propertyType == null)
				{
					//需要直接根据数字里的内容动态获取
					valueAry.push(jsonData);
				}
				else
				{
					//有类型，有可能是基础类型，需要做类型判断
					if(propertyType == RefConts.BOOLEAN_TYPE || propertyType == RefConts.INT_TYPE
						|| propertyType == RefConts.NUMBER_TYPE || propertyType == RefConts.UINT_TYPE
						|| propertyType == RefConts.STRING_TYPE || propertyType == RefConts.OBJECT_TYPE)
					{
						valueAry.push(jsonData);
					}
					else
					{
						target = RefUtils.refObject(propertyType);
						valueAry.push(target);
						jsonToObject(jsonData,target);
					}
				}
			}
			return valueAry;
		}
		private function getType(obj:Object):Type
		{
			var type:Type = cacheType.get(ClassUtils.forInstance(obj));
			if(type == null)
			{
				type = Type.forInstance(obj);
			}
			return type;
		}
	}
}